#ifndef MY_VECTOR_H
#define MY_VECTOR_H

#include <iostream>
#include <memory>

namespace MyVector
{

template<class T>
class Vector{
public:
    using iterator = T*;
    using value_type = T;

    Vector()
        :_start(nullptr)
        , _finish(nullptr)
        , _end_of_storage(nullptr)
    {
        std::cout << "Vector()" << std::endl;
    }
    
    ~Vector()
    {
        std::cout << "~Vector()" << std::endl;
        if (_start) {
            while (_finish != _start) {
                _alloc.destroy(--_finish);
            }
            _alloc.deallocate(_start, capacity());
        }
        _start = nullptr;
        _finish = nullptr;
        _end_of_storage = nullptr;
    }

    iterator begin() {
        return _start;
    }
    iterator end() {
        return _finish;
    }
    int size() {
        return _finish - _start;
    }
    int capacity() {
        return _end_of_storage - _start;
    }

    void push_back(const T& value) {
        if (size() == capacity()) {
            reallocate();
        }
        if (size() < capacity()) {
            _alloc.construct(_finish++, value);
        }
    }

    void pop_back() {
        if (size() > 0) {
            _alloc.destroy(--_finish);
        }
    }
private:
    static std::allocator<T> _alloc;

    T* _start;
    T* _finish;
    T* _end_of_storage;

    // 重新分配内存
    void reallocate() {
        int oldCapacity = capacity();
        // 初次申请为 1, 其他基于当前 oldCapacity 的 2 倍
        int newCapacity = oldCapacity > 0 ? 2 * oldCapacity : 1;
        std::cout << "Vector::reallocate() : oldCapacity = " << oldCapacity << ", newCapacity = " << newCapacity << std::endl;
        iterator pTmp = _alloc.allocate(newCapacity);
        if (_start) {
            std::uninitialized_copy(_start, _finish, pTmp);
            while (_start != _finish) {
                _alloc.destroy(--_finish);
            }
            _alloc.deallocate(_start, capacity());
        }

        _start = pTmp;
        _finish = _start + oldCapacity;
        _end_of_storage = _start + newCapacity;
    }
}; // end of class Vector

template <class T>
std::allocator<T> Vector<T>::_alloc;

} // end of namespace MyVector

#endif // MY_VECTOR_H